//
//  main.c
//  LinearQueue
//
//  Created by Shawn Li on 2020/4/15.
//  Copyright © 2020 Shawn. All rights reserved.
//

//本工程主要演示顺序循环队列的实现

#include <stdio.h>
#include "stdlib.h"
#include "math.h"
#include "time.h"

#define MAXSIZE 20

#define SUCCESS 1
#define ERROR 0

#define TRUE 1
#define FALSE 0

typedef int ElementType;

typedef int Status;

//定义顺序队列
typedef struct LinearQueue{
    //    数据域
    ElementType data[MAXSIZE];
    //    队头 出队在此处进行
    int front;
    //    队尾 入队在此进行
    int rear;
}LinearQueue;


/// 队列的初始化
/// @param q 队列
Status queueInit(LinearQueue *q){
    q->front = q->rear = 0;
    return SUCCESS;
}


/// 清空队列
/// @param q 队列
Status queueClear(LinearQueue *q){
    q->front = q->rear = 0;
    return SUCCESS;
}

/// 获取队列的长度
/// @param q 队列
int queueGetCount(LinearQueue q){
    //    注意循环可能会出现负数，所以需要 + MAXSIZE
    return (q.rear + MAXSIZE - q.front) % MAXSIZE;
}


/// 判断队列是否为空
/// @param q 队列
Status queueIsEmpty(LinearQueue q){
    return 0 == queueGetCount(q);
}


/// 判断队列是否满了
/// @param q 队列
Status queueIsFull(LinearQueue q){
    return q.front == (q.rear + 1) % MAXSIZE;
}


/// 遍历并输出队列
/// @param q 队列
Status queuePrint(LinearQueue q){
    if (queueIsEmpty(q)) {
        printf("队列为空！\n");
        return ERROR;
    }
//    printf("从front开始倒序输出元素，这个顺序就是入队的顺序，也是将来出队的顺序。");
    printf("\n队列元素：");
    for (int i = 0; i < queueGetCount(q); i++) {
        int index = ((q.front + i) % MAXSIZE);
        ElementType e = q.data[index];
        printf("%d, ", e);
    }
    printf("\n\n");
    return SUCCESS;
}


/// 入队
/// @param q 队列
/// @param e 入队元素
Status queueIn(LinearQueue *q, ElementType e){
    if (queueIsFull(*q)) {
        printf("队列已经满了！\n");
        return ERROR;
    }
    q->data[q->rear] = e;
    q->rear = ((q->rear + 1) % MAXSIZE);
    return SUCCESS;
}


/// 出队
/// @param q 队列
/// @param e 出队元素带回
Status queueOut(LinearQueue *q, ElementType *e){
    if (queueIsEmpty(*q)) {
        printf("队列已经空了！\n");
        return ERROR;
    }
    *e = q->data[q->front];
    q->front = (q->front + 1) % MAXSIZE;
    return SUCCESS;
}

int main(int argc, const char * argv[]) {
    // insert code here...
    printf("Hello, World!\n本工程主要演示顺序循环队列的实现！\n");
    
    LinearQueue q;
    ElementType e;
    
    queueInit(&q);
    queuePrint(q);
    
    for (int i = 0; i < 21; i++) {
        if (queueIn(&q, i)) {
            queuePrint(q);
        }
    }
    
    printf("\n\n\n***********************************\n\n\n");
    
    for (int i = 0; i < 21; i++) {
        if (queueOut(&q, &e)) {
            printf("\n------出栈元素为：%d\n", e);
            queuePrint(q);
        }
    }
    
    return 0;
}
